package com.free.semantic.core.funcimpl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultipleKeyMap {

    private int keyLength;
    private Map<MultipleKey, String> dataMap = new HashMap<>();

    public MultipleKeyMap() {
    }

    public void setKeyLength(int keyLength) {
        this.keyLength = keyLength;
    }

    public Map<MultipleKey, String> getDataMap() {
        return dataMap;
    }

    public void setDataMap(Map<MultipleKey, String> dataMap) {
        this.dataMap = dataMap;
    }

    public MultipleKeyMap(int keyLength) {
        this.keyLength = keyLength;
    }

    public static MultipleKeyMap fromArray(String[][] map) {
        if (map.length == 0) {
            return new MultipleKeyMap(0);
        }
        int length = map[0].length;
        MultipleKeyMap keyMap = new MultipleKeyMap(length - 1);
        for (String[] key : map) {
            String[] strings = Arrays.copyOf(key, keyMap.keyLength);
            keyMap.store(strings, key[keyMap.keyLength]);
        }
        return keyMap;
    }

    public int getKeyLength() {
        return keyLength;
    }

    public void store(String[] key, String value) {
        assert key.length == keyLength;
        dataMap.put(new MultipleKey(key), value);
    }

    public String get(String[] key) {
        assert key.length == keyLength;
        return dataMap.get(new MultipleKey(key));
    }

    public String get(List<String> key) {
        assert key.size() == keyLength;
        return dataMap.get(new MultipleKey(key));
    }

    public static class MultipleKey {

        String[] key;

        public MultipleKey(String[] key) {
            this.key = key;
        }

        public MultipleKey(List<String> key) {
            this.key = key.stream().toArray(value -> new String[key.size()]);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            MultipleKey that = (MultipleKey) o;
            return Arrays.equals(key, that.key);
        }

        public String[] getKey() {
            return key;
        }

        public void setKey(String[] key) {
            this.key = key;
        }


        @Override
        public int hashCode() {
            return Arrays.hashCode(key);
        }
    }

}
